Data

Parameters

suffix = "01_22"
data_to_read = ""

functions

source_from_github(repositoy = "DEG_functions",version = "0.2.1")
source_from_github(repositoy = "HMSC_functions",version = "0.1.0",script_name = "functions.R")

MYB expression

all_acc_cancer_cells = SetIdent(object = all_acc_cancer_cells,value = "patient.ident") #active snn graph
FeaturePlot(object = all_acc_cancer_cells,features = "MYB",label = T)

CNV

new.cluster.ids <- c("cancer", #0
                     "cancer", #1
                     "CAF", #2
                     "cancer", #3
                     "Endothelial", #4
                     "cancer", #5
                     "cancer", #6
                     "CAF", #7
                     "CAF", #8
                     "CAF", #9
                     "cancer", #10
                     "CAF", #11
                     "cancer", #12
                     "cancer", #13
                     "cancer", #14
                     "cancer", #15
                     "cancer", #16
                     "WBC", #17
                     "CAF" #18
                     )
#rename idents:
acc_all_cells = SetIdent(object = acc_all_cells,value = "RNA_snn_res.1") #active snn graph
names(new.cluster.ids) <- levels(acc_all_cells) #add snn graph levels to new.cluster.ids
acc_all_cells@meta.data[["seurat_clusters"]] = acc_all_cells@meta.data[["RNA_snn_res.1"]]
acc_all_cells = SetIdent(object = acc_all_cells,value = "seurat_clusters")
acc_all_cells <- RenameIdents(acc_all_cells, new.cluster.ids) 

# divide "cancer" into patients:
cell_types = acc_all_cells@active.ident %>% as.data.frame()
cell_types[,1]<- as.character(cell_types[,1])
cell_types = cbind(cell_types,acc_all_cells$patient.ident) %>% setnames(old = names(.), 
         new = c('cell_type','patient'))
cell_types[cell_types$cell_type == "cancer",] = cell_types[cell_types$cell_type == "cancer",2]


# hmsc_rows = (startsWith(x = rownames(cell_types),prefix = "ACC.plate2") | startsWith(x = rownames(cell_types),prefix = "ACC1.")) & cell_types[,1] == "cancer" 
# acc_rows = !(startsWith(x = rownames(cell_types),prefix = "ACC.plate2") | startsWith(x = rownames(cell_types),prefix = "ACC1.")) & cell_types[,1] == "cancer" 
# cell_types[,1][hmsc_rows]  = "HMSC"
# cell_types[,1][acc_rows]  = "ACC"

#add to metadata:
cell_types[,2] = NULL 
cell_types[cell_types$cell_type == "ACC1",] = "HMSC"
acc_all_cells = AddMetaData(object =acc_all_cells ,metadata = cell_types,col.name = "cell.type")

CNV plot

Original score

original_myo_genes = c( "TP63", "TP73", "CAV1", "CDH3", "KRT5", "KRT14", "ACTA2", "TAGLN", "MYLK", "DKK3")
original_lum_genes = c("KIT", "EHF", "ELF5", "KRT7", "CLDN3", "CLDN4", "CD24", "LGALS3", "LCN2", "SLPI" )
myoscore=apply(all_acc_cancer_cells@assays[["RNA"]][original_myo_genes,],2,mean)
lescore=apply(all_acc_cancer_cells@assays[["RNA"]][original_lum_genes,],2,mean)
all_acc_cancer_cells=AddMetaData(all_acc_cancer_cells,lescore-myoscore,"luminal_over_myo")
FeaturePlot(object = all_acc_cancer_cells,features = "luminal_over_myo")

data = FetchData(object = all_acc_cancer_cells,vars = "luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=luminal_over_myo)) + 
  geom_density() 
)

myoscore=apply(acc1_cancer_cells@assays[["RNA"]][original_myo_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]][original_lum_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "luminal_over_myo")

data = FetchData(object = acc1_cancer_cells,vars = "luminal_over_myo")
print(
    data %>% 
    ggplot(aes( x=luminal_over_myo)) + 
    geom_density() 
  )

0.35 Most correlated score

Myo genes

myo_protein_markers = c("CNN1", "TP63","ACTA2")
top_myo  = top_correlated(dataset = acc1_cancer_cells, genes = myo_protein_markers,threshold = 0.35)
print("Number of genes = " %>% paste(length(top_myo)))
[1] "Number of genes =  20"
message("Names of genes:")
Names of genes:
top_myo %>% head(30)
 [1] "COL16A1"     "RP1-39G22.4" "ACTG2"       "CD200"       "MYLK"        "TP63"        "KCNMB1"      "ADAMTS2"     "LOXL2"      
[10] "TPM2"        "CLIC3"       "SNCG"        "ACTA2"       "TAGLN"       "A2M"         "NGFR"        "CNN1"        "PPP1R14A"   
[19] "MYL9"        "POM121L9P"  
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_myo,original_myo_genes) 
[1] "MYLK"  "TP63"  "ACTA2" "TAGLN"
myo_enrich_res = genes_vec_enrichment(genes = top_myo,background = rownames(acc1_cancer_cells),homer = T,title = "myo top enrichment",custom_pathways = luminal_gs)

myo_enrich_res

Lum genes

lum_protein_markers = c("KIT")
top_lum  = top_correlated(dataset = acc1_cancer_cells, genes = lum_protein_markers,threshold = 0.35)
Warning in cor(expression %>% t(), markers_average) :
  the standard deviation is zero
print("Number of genes = " %>% paste(length(top_lum)))
[1] "Number of genes =  22"
message("Names of genes:")
Names of genes:
top_lum %>% head(30)
 [1] "FBXO44"        "USP48"         "MPC2"          "SLC19A2"       "ATL2"          "B3GNT2"        "AC093162.5"   
 [8] "MAP2"          "KIT"           "GLRB"          "EFNA5"         "PCDHGB7"       "SLC29A1"       "SASH1"        
[15] "ALDH3B2"       "CCND1"         "RP11-254B13.1" "VSIG10"        "NDFIP2"        "SUSD6"         "SPPL2A"       
[22] "DSC2"         
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_lum,original_lum_genes) 
[1] "KIT"
lum_enrich_res = genes_vec_enrichment(genes = top_lum,background = rownames(acc1_cancer_cells),homer = T,title = "lum top enrichment",custom_pathways = luminal_gs)

lum_enrich_res

top correlated score

myoscore=apply(acc1_cancer_cells@assays[["RNA"]][top_myo,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]][top_lum,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"top_cor_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "top_cor_luminal_over_myo")


data = FetchData(object = acc1_cancer_cells,vars = "top_cor_luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=top_cor_luminal_over_myo)) + 
  geom_density() 
)

enriched genes score

rownames(lum_enrich_res) = lum_enrich_res$pathway_name
lum_enriched_genes = lum_enrich_res[1,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,lum_protein_markers) #add original markers
rownames(myo_enrich_res) = myo_enrich_res$pathway_name
myo_enriched_genes = myo_enrich_res[1,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,myo_protein_markers) #add original markers
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")


data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=enriched_luminal_over_myo)) + 
  geom_density() 
)

0.2 Most correlated score

myo Genes

myo_protein_markers = c("CNN1", "TP63","ACTA2")
top_myo  = top_correlated(dataset = acc1_cancer_cells, genes = myo_protein_markers,threshold = 0.2)
print("Number of genes = " %>% paste(length(top_myo)))
[1] "Number of genes =  473"
message("Names of genes:")
Names of genes:
top_myo %>% head(30)
 [1] "MIR429"        "EXOSC10"       "PLOD1"         "TNFRSF8"       "PDPN"          "FBLIM1"        "RP11-276H7.3" 
 [8] "HSPG2"         "EPHA8"         "IFNLR1"        "GRHL3"         "RP3-426I6.6"   "SDC3"          "RP11-490K7.1" 
[15] "RP11-73M7.1"   "TINAGL1"       "COL16A1"       "RP1-117O3.2"   "RP11-435D7.3"  "RP1-39G22.4"   "SCMH1"        
[22] "RP5-850O15.4"  "RP5-866L20.3"  "NEXN"          "RP4-714D9.2"   "RP5-837M10.3"  "RP5-964H19.1"  "CSF1"         
[29] "RP11-498A13.1" "RP11-96K19.2" 
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_myo,original_myo_genes) 
[1] "MYLK"  "TP63"  "ACTA2" "DKK3"  "TAGLN" "CDH3" 
myo_enrich_res = genes_vec_enrichment(genes = top_myo,background = rownames(acc1_cancer_cells),homer = T,title = "myo top enrichment",custom_pathways = luminal_gs)

myo_enrich_res

Lum Genes

lum_protein_markers = c("KIT")
top_lum  = top_correlated(dataset = acc1_cancer_cells, genes = lum_protein_markers,threshold = 0.2)
Warning in cor(expression %>% t(), markers_average) :
  the standard deviation is zero
print("Number of genes = " %>% paste(length(top_lum)))
[1] "Number of genes =  1535"
message("Names of genes:")
Names of genes:
top_lum %>% head(30)
 [1] "RP11-206L10.11" "HES4"           "RP11-54O7.18"   "CPTP"           "RP3-395M20.8"   "TNFRSF14"       "RPL22"         
 [8] "ICMT"           "ERRFI1"         "RERE"           "H6PD"           "TMEM201"        "NMNAT1"         "UBE4B"         
[15] "APITD1-CORT"    "CENPS"          "RP4-635E18.7"   "FBXO2"          "FBXO44"         "UQCRHL"         "MST1P2"        
[22] "SDHB"           "PADI2"          "ARHGEF10L"      "AKR7A2"         "TMCO4"          "EIF4G3"         "USP48"         
[29] "NIPAL3"         "PIGV"          
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_lum,original_lum_genes) 
[1] "KIT"    "EHF"    "LGALS3"
lum_enrich_res = genes_vec_enrichment(genes = top_lum,background = rownames(acc1_cancer_cells),homer = T,title = "lum top enrichment",custom_pathways = luminal_gs)

lum_enrich_res

correlated genes in original score

myo_intersected = intersect(top_myo,original_myo_genes) 
lum_intersected = intersect(top_lum,original_lum_genes) 
message("genes in myo score:")
genes in myo score:
myo_intersected
[1] "MYLK"  "TP63"  "ACTA2" "DKK3"  "TAGLN" "CDH3" 
message("genes in lum score:")
genes in lum score:
lum_intersected
[1] "KIT"    "EHF"    "LGALS3"
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[c("MYLK","TP63" ,"ACTA2", "DKK3", "TAGLN", "CDH3" ),],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[c("KIT" ,"EHF",  "LGALS3"),],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")


data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=enriched_luminal_over_myo)) + 
  geom_density() 
)

enriched genes

rownames(lum_enrich_res) = lum_enrich_res$pathway_name
lum_enriched_genes = lum_enrich_res[3,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,lum_protein_markers) #add original markers
rownames(myo_enrich_res) = myo_enrich_res$pathway_name
myo_enriched_genes = myo_enrich_res[3,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,myo_protein_markers) #add original markers
message("genes in myo score:")
genes in myo score:
myo_enriched_genes
 [1] "FBLIM1"  "NEXN"    "NMNAT2"  "MYLK"    "CCDC50"  "IGFBP7"  "RAI14"   "ARAP3"   "SPARC"   "CALD1"   "LOXL2"   "COL5A1" 
[13] "ACTA2"   "DKK3"    "MSRB3"   "COL4A1"  "ACTN1"   "TPM1"    "TGFB1I1" "ADORA2B" "MXRA7"   "CNN1"    "TP63"    "ACTA2"  
message("genes in lum score:")
genes in lum score:
lum_enriched_genes
 [1] "PADI2"      "PATJ"       "PEX11B"     "APH1A"      "C1orf43"    "EFNA4"      "NECTIN4"    "SCYL3"      "ELF3"      
[10] "SOX13"      "IRF6"       "MED28"      "EPB41L4A"   "RGL2"       "C6orf132"   "TPD52L1"    "ICA1"       "MACC1"     
[19] "TRPS1"      "FAM83H"     "RASEF"      "ARRDC1"     "COMMD3"     "ANK3"       "GSTO2"      "PDCD4"      "EHF"       
[28] "ALDH3B2"    "SHANK2"     "SORL1"      "FKBP4"      "PTPN6"      "DUSP16"     "RERG"       "ADCY6"      "ERBB3"     
[37] "ERP29"      "SUSD6"      "RPS6KA5"    "SPINT1"     "FEM1B"      "TLE3"       "SCAMP2"     "CLN3"       "ADGRG1"    
[46] "ATP2C2"     "GGT6"       "MYO1D"      "ST6GALNAC2" "CYB5A"      "BLVRB"      "VRK3"       "SYCP2"      "TMPRSS2"   
[55] "LIMK2"      "KIT"       
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")


data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=enriched_luminal_over_myo)) + 
  geom_density() 
)

enriched genes and in original score

myo_enriched_genes = myo_enriched_genes[myo_enriched_genes %in% original_myo_genes]
lum_enriched_genes = lum_enriched_genes[lum_enriched_genes %in% original_lum_genes]

message("genes in myo score:")
genes in myo score:
myo_enriched_genes
[1] "MYLK"  "ACTA2" "DKK3"  "TP63"  "ACTA2"
message("genes in lum score:")
genes in lum score:
lum_enriched_genes
[1] "EHF" "KIT"
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")


data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
  data %>% 
  ggplot(aes( x=enriched_luminal_over_myo)) + 
  geom_density() 
)

HPV

Only HMSC cancer cells:

data = FetchData(object = acc1_cancer_cells,vars = "HPV33.reads")
print(
  data %>% 
  ggplot(aes( x=HPV33.reads)) + 
  geom_density()
)

LS0tCnRpdGxlOiAiVGl0bGUiCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQotLS0KCiMjIERhdGEKCmBgYHtyfQphY2MxX2NhbmNlcl9jZWxscyA9IHJlYWRSRFMoIi4vRGF0YS9hY2MxX2NhbmNlcl9jZWxsc18xNUtuQ291bnRfVjMuUkRTIikKYWxsX2FjY19jYW5jZXJfY2VsbHMgPSByZWFkUkRTKCIuL0RhdGEvYWNjX2NhbmNlcl9jZWxsc19WMy5SRFMiKQphY2NfYWxsX2NlbGxzID0gcmVhZFJEUygiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX3dpdGhfQUNDMV8uUkRTIikKbHVtaW5hbF9wYXRod2F5cyA9IGMoIkNIQVJBRkVfQlJFQVNUX0NBTkNFUl9MVU1JTkFMX1ZTX0JBU0FMX0ROIiwiQ0hBUkFGRV9CUkVBU1RfQ0FOQ0VSX0xVTUlOQUxfVlNfQkFTQUxfVVAiLCJDSEFSQUZFX0JSRUFTVF9DQU5DRVJfTFVNSU5BTF9WU19NRVNFTkNIWU1BTF9ETiIsIkNIQVJBRkVfQlJFQVNUX0NBTkNFUl9MVU1JTkFMX1ZTX01FU0VOQ0hZTUFMX1VQIiwiSFVQRVJfQlJFQVNUX0JBU0FMX1ZTX0xVTUlOQUxfRE4iLCJMSU1fTUFNTUFSWV9MVU1JTkFMX1BST0dFTklUT1JfVVAiLCJTTUlEX0JSRUFTVF9DQU5DRVJfTFVNSU5BTF9CX1VQIiApCgojIGFkZCBsdW1pbmFsIHBhdGh3YXlzCmx1bWluYWxfZ3MgPSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIikgJT4lYXMuZGF0YS5mcmFtZSgpICU+JSBkcGx5cjo6ZmlsdGVyKGdzX25hbWUgJWluJSBsdW1pbmFsX3BhdGh3YXlzKSU+JSBkcGx5cjo6ZGlzdGluY3QoZ3NfbmFtZSwgZ2VuZV9zeW1ib2wpICU+JSBhcy5kYXRhLmZyYW1lKCkKCmBgYAoKIyMgUGFyYW1ldGVycwoKYGBge3Igd2FybmluZz1GQUxTRX0Kc3VmZml4ID0gIjAxXzIyIgpkYXRhX3RvX3JlYWQgPSAiIgpgYGAKCgojIyBmdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiREVHX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjIuMSIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiSE1TQ19mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC4xLjAiLHNjcmlwdF9uYW1lID0gImZ1bmN0aW9ucy5SIikKYGBgCgoKIyBNWUIgZXhwcmVzc2lvbgoKYGBge3IgZmlnLndpZHRoPTEwfQphbGxfYWNjX2NhbmNlcl9jZWxscyA9IFNldElkZW50KG9iamVjdCA9IGFsbF9hY2NfY2FuY2VyX2NlbGxzLHZhbHVlID0gInBhdGllbnQuaWRlbnQiKSAjYWN0aXZlIHNubiBncmFwaApGZWF0dXJlUGxvdChvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyxmZWF0dXJlcyA9ICJNWUIiLGxhYmVsID0gVCkKYGBgCiMgQ05WCgpgYGB7cn0KI3NldCBjZWxsIHR5cGVzCm5ldy5jbHVzdGVyLmlkcyA8LSBjKCJjYW5jZXIiLCAjMAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzEKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICMyCiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMwogICAgICAgICAgICAgICAgICAgICAiRW5kb3RoZWxpYWwiLCAjNAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzUKICAgICAgICAgICAgICAgICAgICAgImNhbmNlciIsICM2CiAgICAgICAgICAgICAgICAgICAgICJDQUYiLCAjNwogICAgICAgICAgICAgICAgICAgICAiQ0FGIiwgIzgKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICM5CiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTAKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICMxMQogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzEyCiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTMKICAgICAgICAgICAgICAgICAgICAgImNhbmNlciIsICMxNAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzE1CiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTYKICAgICAgICAgICAgICAgICAgICAgIldCQyIsICMxNwogICAgICAgICAgICAgICAgICAgICAiQ0FGIiAjMTgKICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCgpgYGB7ciBmaWcuc2hvdz0naGlkZSd9CiNyZW5hbWUgaWRlbnRzOgphY2NfYWxsX2NlbGxzID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2FsbF9jZWxscyx2YWx1ZSA9ICJSTkFfc25uX3Jlcy4xIikgI2FjdGl2ZSBzbm4gZ3JhcGgKbmFtZXMobmV3LmNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoYWNjX2FsbF9jZWxscykgI2FkZCBzbm4gZ3JhcGggbGV2ZWxzIHRvIG5ldy5jbHVzdGVyLmlkcwphY2NfYWxsX2NlbGxzQG1ldGEuZGF0YVtbInNldXJhdF9jbHVzdGVycyJdXSA9IGFjY19hbGxfY2VsbHNAbWV0YS5kYXRhW1siUk5BX3Nubl9yZXMuMSJdXQphY2NfYWxsX2NlbGxzID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2FsbF9jZWxscyx2YWx1ZSA9ICJzZXVyYXRfY2x1c3RlcnMiKQphY2NfYWxsX2NlbGxzIDwtIFJlbmFtZUlkZW50cyhhY2NfYWxsX2NlbGxzLCBuZXcuY2x1c3Rlci5pZHMpIAoKIyBkaXZpZGUgImNhbmNlciIgaW50byBwYXRpZW50czoKY2VsbF90eXBlcyA9IGFjY19hbGxfY2VsbHNAYWN0aXZlLmlkZW50ICU+JSBhcy5kYXRhLmZyYW1lKCkKY2VsbF90eXBlc1ssMV08LSBhcy5jaGFyYWN0ZXIoY2VsbF90eXBlc1ssMV0pCmNlbGxfdHlwZXMgPSBjYmluZChjZWxsX3R5cGVzLGFjY19hbGxfY2VsbHMkcGF0aWVudC5pZGVudCkgJT4lIHNldG5hbWVzKG9sZCA9IG5hbWVzKC4pLCAKICAgICAgICAgbmV3ID0gYygnY2VsbF90eXBlJywncGF0aWVudCcpKQpjZWxsX3R5cGVzW2NlbGxfdHlwZXMkY2VsbF90eXBlID09ICJjYW5jZXIiLF0gPSBjZWxsX3R5cGVzW2NlbGxfdHlwZXMkY2VsbF90eXBlID09ICJjYW5jZXIiLDJdCgoKIyBobXNjX3Jvd3MgPSAoc3RhcnRzV2l0aCh4ID0gcm93bmFtZXMoY2VsbF90eXBlcykscHJlZml4ID0gIkFDQy5wbGF0ZTIiKSB8IHN0YXJ0c1dpdGgoeCA9IHJvd25hbWVzKGNlbGxfdHlwZXMpLHByZWZpeCA9ICJBQ0MxLiIpKSAmIGNlbGxfdHlwZXNbLDFdID09ICJjYW5jZXIiIAojIGFjY19yb3dzID0gIShzdGFydHNXaXRoKHggPSByb3duYW1lcyhjZWxsX3R5cGVzKSxwcmVmaXggPSAiQUNDLnBsYXRlMiIpIHwgc3RhcnRzV2l0aCh4ID0gcm93bmFtZXMoY2VsbF90eXBlcykscHJlZml4ID0gIkFDQzEuIikpICYgY2VsbF90eXBlc1ssMV0gPT0gImNhbmNlciIgCiMgY2VsbF90eXBlc1ssMV1baG1zY19yb3dzXSAgPSAiSE1TQyIKIyBjZWxsX3R5cGVzWywxXVthY2Nfcm93c10gID0gIkFDQyIKCiNhZGQgdG8gbWV0YWRhdGE6CmNlbGxfdHlwZXNbLDJdID0gTlVMTCAKY2VsbF90eXBlc1tjZWxsX3R5cGVzJGNlbGxfdHlwZSA9PSAiQUNDMSIsXSA9ICJITVNDIgphY2NfYWxsX2NlbGxzID0gQWRkTWV0YURhdGEob2JqZWN0ID1hY2NfYWxsX2NlbGxzICxtZXRhZGF0YSA9IGNlbGxfdHlwZXMsY29sLm5hbWUgPSAiY2VsbC50eXBlIikKYGBgCgpgYGB7ciBmaWcud2lkdGg9MTB9CmxpYnJhcnkoaW5mZXJjbnYpCmxpYnJhcnkodGlkeXZlcnNlKQphY2NfYW5ub3RhdGlvbiAgPSBhcy5kYXRhLmZyYW1lKGFjY19hbGxfY2VsbHNAbWV0YS5kYXRhWywiY2VsbC50eXBlIixkcm9wID0gRl0pCmFjY19hbm5vdGF0aW9uID0gYWNjX2Fubm90YXRpb24gJT4lIHJvd25hbWVzX3RvX2NvbHVtbigib3JpZy5pZGVudCIpIAphY2NfYW5ub3RhdGlvbiA9IGFjY19hbm5vdGF0aW9uICU+JSBtdXRhdGUob3JpZy5pZGVudCA9IGdzdWIoeCA9IGFjY19hbm5vdGF0aW9uJG9yaWcuaWRlbnQscGF0dGVybiA9ICJcXC4iLCByZXBsYWNlbWVudCA9ICItIikgJT4lIAogIGdzdWIocGF0dGVybiA9ICJfIiwgcmVwbGFjZW1lbnQgPSAiLSIpKQogIAoKd3JpdGUudGFibGUoYWNjX2Fubm90YXRpb24sICIuL0RhdGEvaW5mZXJDTlYvYWNjX2Fubm90YXRpb24udHh0IiwgYXBwZW5kID0gRkFMU0UsIAogICAgICAgICAgICBzZXAgPSAiXHQiLCBkZWMgPSAiLiIscm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IEYpCgppbmZlcmNudl9vYmogPSBDcmVhdGVJbmZlcmNudk9iamVjdChyYXdfY291bnRzX21hdHJpeD0iLi9EYXRhL2luZmVyQ05WL2FsbC40aWNudi50eHQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnNfZmlsZT0iLi9EYXRhL2luZmVyQ05WL2FjY19hbm5vdGF0aW9uLnR4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGltPSJcdCIsZ2VuZV9vcmRlcl9maWxlPSIuL0RhdGEvaW5mZXJDTlYvZ2VuY29kZV92MTlfZ2VuZV9wb3MudHh0IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAscmVmX2dyb3VwX25hbWVzPWMoIkNBRiIsICJFbmRvdGhlbGlhbCIsICJXQkMiKSkgI2dyb3VwcyBvZiBub3JtYWwgY2VsbHMKCmluZmVyY252X29ial9kZWZhdWx0ID0gaW5mZXJjbnY6OnJ1bihpbmZlcmNudl9vYmosIGN1dG9mZj0xLCBvdXRfZGlyPScuL0RhdGEvaW5mZXJDTlYvaW5mZXJjbnZfb3V0cHV0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfYnlfZ3JvdXBzPVQsIHBsb3Rfc3RlcHM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZW5vaXNlPVRSVUUsIEhNTT1GQUxTRSwgbm9fcHJlbGltX3Bsb3Q9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuZ19yZXM9MzAwKQpwbG90X2NudihpbmZlcmNudl9vYmpfZGVmYXVsdCwgb3V0cHV0X2Zvcm1hdCA9ICJwbmciLCAgd3JpdGVfZXhwcl9tYXRyaXggPSBGQUxTRSxvdXRfZGlyID0gIi4vRGF0YS9pbmZlckNOVi8iLHBuZ19yZXMJPTgwMCxvYnNfdGl0bGUgPSAiTWFsaWduYW50IGNlbGxzIixyZWZfdGl0bGUgPSAiTm9ybWFsIGNlbGxzIikKCgpjbHVzdGVyLmluZm89RmV0Y2hEYXRhKGFjY19hbGxfY2VsbHMsYygiaWRlbnQiLCJvcmlnLmlkZW50IiwiVU1BUF8xIiwiVU1BUF8yIiwibkNvdW50X1JOQSIsIm5GZWF0dXJlX1JOQSIsInBlcmNlbnQubXQiLCJwYXRpZW50LmlkZW50Iiwic2V1cmF0X2NsdXN0ZXJzIikpCmNsdXN0ZXIuaW5mbyRjZWxsPXJvd25hbWVzKGNsdXN0ZXIuaW5mbykKCmxpYnJhcnkobGltbWEpCnNtb290aGVkPWFwcGx5KGluZmVyY252X29ial9kZWZhdWx0QGV4cHIuZGF0YSwyLHRyaWN1YmVNb3ZpbmdBdmVyYWdlLCBzcGFuPTAuMDEpCmNuc2lnPXNxcnQoYXBwbHkoKHNtb290aGVkLTEpXjIsMixtZWFuKSkKdW1hcD1jbHVzdGVyLmluZm8KbmFtZXMoY25zaWcpPXVtYXAkY2VsbAoKYWNjX2FsbF9jZWxscyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSBhY2NfYWxsX2NlbGxzLCBtZXRhZGF0YSA9IGNuc2lnLCBjb2wubmFtZSA9ICJjb3B5bnVtYmVyIikKYWNjX2FsbF9jZWxscyA9IFNldElkZW50KG9iamVjdCA9IGFjY19hbGxfY2VsbHMsdmFsdWUgPSAiY2VsbC50eXBlIikKRmVhdHVyZVBsb3QoYWNjX2FsbF9jZWxscywgImNvcHludW1iZXIiLHB0LnNpemUgPSAxLCBjb2xzID0gYygibGlnaHRibHVlIiwib3JhbmdlIiwicmVkIiwiZGFya3JlZCIpLGxhYmVsID0gVCxyZXBlbCA9IFQpCmBgYAoKCgohW0NOViBwbG90XSgvc2NpL2xhYnMveW90YW1kL2xhYl9zaGFyZS9hdmlzaGFpLndpemVsL1JfcHJvamVjdHMvSE1TQy9EYXRhL2luZmVyQ05WL2luZmVyY252LnBuZykKCiMjIE9yaWdpbmFsIHNjb3JlCmBgYHtyfQpvcmlnaW5hbF9teW9fZ2VuZXMgPSBjKCAiVFA2MyIsICJUUDczIiwgIkNBVjEiLCAiQ0RIMyIsICJLUlQ1IiwgIktSVDE0IiwgIkFDVEEyIiwgIlRBR0xOIiwgIk1ZTEsiLCAiREtLMyIpCm9yaWdpbmFsX2x1bV9nZW5lcyA9IGMoIktJVCIsICJFSEYiLCAiRUxGNSIsICJLUlQ3IiwgIkNMRE4zIiwgIkNMRE40IiwgIkNEMjQiLCAiTEdBTFMzIiwgIkxDTjIiLCAiU0xQSSIgKQpgYGAKCmBgYHtyfQpteW9zY29yZT1hcHBseShhbGxfYWNjX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bb3JpZ2luYWxfbXlvX2dlbmVzLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFsbF9hY2NfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXVtvcmlnaW5hbF9sdW1fZ2VuZXMsXSwyLG1lYW4pCmFsbF9hY2NfY2FuY2VyX2NlbGxzPUFkZE1ldGFEYXRhKGFsbF9hY2NfY2FuY2VyX2NlbGxzLGxlc2NvcmUtbXlvc2NvcmUsImx1bWluYWxfb3Zlcl9teW8iKQpGZWF0dXJlUGxvdChvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyxmZWF0dXJlcyA9ICJsdW1pbmFsX292ZXJfbXlvIikKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyx2YXJzID0gImx1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PWx1bWluYWxfb3Zlcl9teW8pKSArIAogIGdlb21fZGVuc2l0eSgpIAopCmBgYAoKYGBge3J9Cm15b3Njb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXVtvcmlnaW5hbF9teW9fZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dW29yaWdpbmFsX2x1bV9nZW5lcyxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwibHVtaW5hbF9vdmVyX215byIpCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLGZlYXR1cmVzID0gImx1bWluYWxfb3Zlcl9teW8iKQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAibHVtaW5hbF9vdmVyX215byIpCnByaW50KAogICAgZGF0YSAlPiUgCiAgICBnZ3Bsb3QoYWVzKCB4PWx1bWluYWxfb3Zlcl9teW8pKSArIAogICAgZ2VvbV9kZW5zaXR5KCkgCiAgKQpgYGAKCiMjIDAuMzUgTW9zdCBjb3JyZWxhdGVkIHNjb3JlIHsudGFic2V0fQoKIyMjIE15byBnZW5lcwoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGNvbGxhcHNlPVR9Cm15b19wcm90ZWluX21hcmtlcnMgPSBjKCJDTk4xIiwgIlRQNjMiLCJBQ1RBMiIpCnRvcF9teW8gID0gdG9wX2NvcnJlbGF0ZWQoZGF0YXNldCA9IGFjYzFfY2FuY2VyX2NlbGxzLCBnZW5lcyA9IG15b19wcm90ZWluX21hcmtlcnMsdGhyZXNob2xkID0gMC4zNSkKcHJpbnQoIk51bWJlciBvZiBnZW5lcyA9ICIgJT4lIHBhc3RlKGxlbmd0aCh0b3BfbXlvKSkpCm1lc3NhZ2UoIk5hbWVzIG9mIGdlbmVzOiIpCnRvcF9teW8gJT4lIGhlYWQoMzApCm1lc3NhZ2UoIkdlbmVzIHRoYXQgYWxzbyBhcGVhcmVkIGluIHRoZSBvcmlnaW5hbCBzY29yZToiKQppbnRlcnNlY3QodG9wX215byxvcmlnaW5hbF9teW9fZ2VuZXMpIApgYGAKYGBge3J9Cm15b19lbnJpY2hfcmVzID0gZ2VuZXNfdmVjX2VucmljaG1lbnQoZ2VuZXMgPSB0b3BfbXlvLGJhY2tncm91bmQgPSByb3duYW1lcyhhY2MxX2NhbmNlcl9jZWxscyksaG9tZXIgPSBULHRpdGxlID0gIm15byB0b3AgZW5yaWNobWVudCIsY3VzdG9tX3BhdGh3YXlzID0gbHVtaW5hbF9ncykKbXlvX2VucmljaF9yZXMKYGBgCiMjIyBMdW0gZ2VuZXMKYGBge3J9Cmx1bV9wcm90ZWluX21hcmtlcnMgPSBjKCJLSVQiKQp0b3BfbHVtICA9IHRvcF9jb3JyZWxhdGVkKGRhdGFzZXQgPSBhY2MxX2NhbmNlcl9jZWxscywgZ2VuZXMgPSBsdW1fcHJvdGVpbl9tYXJrZXJzLHRocmVzaG9sZCA9IDAuMzUpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX2x1bSkpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbHVtICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9sdW0sb3JpZ2luYWxfbHVtX2dlbmVzKSAKYGBgCgpgYGB7cn0KbHVtX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9sdW0sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibHVtIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpsdW1fZW5yaWNoX3JlcwpgYGAKIyMjIHRvcCBjb3JyZWxhdGVkIHNjb3JlCmBgYHtyfQpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bdG9wX215byxdLDIsbWVhbikKbGVzY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bdG9wX2x1bSxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwidG9wX2Nvcl9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAidG9wX2Nvcl9sdW1pbmFsX292ZXJfbXlvIikKCmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsdmFycyA9ICJ0b3BfY29yX2x1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PXRvcF9jb3JfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCiMjIyAgZW5yaWNoZWQgZ2VuZXMgc2NvcmUKYGBge3J9CnJvd25hbWVzKGx1bV9lbnJpY2hfcmVzKSA9IGx1bV9lbnJpY2hfcmVzJHBhdGh3YXlfbmFtZQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoX3Jlc1sxLCJnZW5lSUQiXSAlPiUgc3Ryc3BsaXQoc3BsaXQgPSAiLyIpICU+JSAuW1sxXV0gJT4lIGMoLixsdW1fcHJvdGVpbl9tYXJrZXJzKSAjYWRkIG9yaWdpbmFsIG1hcmtlcnMKYGBgCgpgYGB7cn0Kcm93bmFtZXMobXlvX2VucmljaF9yZXMpID0gbXlvX2VucmljaF9yZXMkcGF0aHdheV9uYW1lCm15b19lbnJpY2hlZF9nZW5lcyA9IG15b19lbnJpY2hfcmVzWzEsImdlbmVJRCJdICU+JSBzdHJzcGxpdChzcGxpdCA9ICIvIikgJT4lIC5bWzFdXSAlPiUgYyguLG15b19wcm90ZWluX21hcmtlcnMpICNhZGQgb3JpZ2luYWwgbWFya2VycwpgYGAKCmBgYHtyfQpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1AZGF0YVtteW9fZW5yaWNoZWRfZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbHVtX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyB7LX0KCgojIyAgMC4yIE1vc3QgY29ycmVsYXRlZCBzY29yZSB7LnRhYnNldH0KCiMjIyAgbXlvIEdlbmVzCgoKYGBge3Igd2FybmluZz1GQUxTRX0KbXlvX3Byb3RlaW5fbWFya2VycyA9IGMoIkNOTjEiLCAiVFA2MyIsIkFDVEEyIikKdG9wX215byAgPSB0b3BfY29ycmVsYXRlZChkYXRhc2V0ID0gYWNjMV9jYW5jZXJfY2VsbHMsIGdlbmVzID0gbXlvX3Byb3RlaW5fbWFya2Vycyx0aHJlc2hvbGQgPSAwLjIpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX215bykpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbXlvICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9teW8sb3JpZ2luYWxfbXlvX2dlbmVzKSAKYGBgCgpgYGB7cn0KbXlvX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9teW8sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibXlvIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpteW9fZW5yaWNoX3JlcwpgYGAKIyMjICBMdW0gR2VuZXMKCmBgYHtyfQpsdW1fcHJvdGVpbl9tYXJrZXJzID0gYygiS0lUIikKdG9wX2x1bSAgPSB0b3BfY29ycmVsYXRlZChkYXRhc2V0ID0gYWNjMV9jYW5jZXJfY2VsbHMsIGdlbmVzID0gbHVtX3Byb3RlaW5fbWFya2Vycyx0aHJlc2hvbGQgPSAwLjIpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX2x1bSkpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbHVtICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9sdW0sb3JpZ2luYWxfbHVtX2dlbmVzKSAKYGBgCgpgYGB7cn0KbHVtX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9sdW0sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibHVtIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpsdW1fZW5yaWNoX3JlcwpgYGAKIyMjICBjb3JyZWxhdGVkIGdlbmVzIGluIG9yaWdpbmFsIHNjb3JlCmBgYHtyfQpteW9faW50ZXJzZWN0ZWQgPSBpbnRlcnNlY3QodG9wX215byxvcmlnaW5hbF9teW9fZ2VuZXMpIApsdW1faW50ZXJzZWN0ZWQgPSBpbnRlcnNlY3QodG9wX2x1bSxvcmlnaW5hbF9sdW1fZ2VuZXMpIAptZXNzYWdlKCJnZW5lcyBpbiBteW8gc2NvcmU6IikKbXlvX2ludGVyc2VjdGVkCgptZXNzYWdlKCJnZW5lcyBpbiBsdW0gc2NvcmU6IikKbHVtX2ludGVyc2VjdGVkCgoKbXlvc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbYygiTVlMSyIsIlRQNjMiICwiQUNUQTIiLCAiREtLMyIsICJUQUdMTiIsICJDREgzIiApLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXUBkYXRhW2MoIktJVCIgLCJFSEYiLCAgIkxHQUxTMyIpLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyMgZW5yaWNoZWQgZ2VuZXMKYGBge3J9CnJvd25hbWVzKGx1bV9lbnJpY2hfcmVzKSA9IGx1bV9lbnJpY2hfcmVzJHBhdGh3YXlfbmFtZQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoX3Jlc1szLCJnZW5lSUQiXSAlPiUgc3Ryc3BsaXQoc3BsaXQgPSAiLyIpICU+JSAuW1sxXV0gJT4lIGMoLixsdW1fcHJvdGVpbl9tYXJrZXJzKSAjYWRkIG9yaWdpbmFsIG1hcmtlcnMKYGBgCgpgYGB7cn0Kcm93bmFtZXMobXlvX2VucmljaF9yZXMpID0gbXlvX2VucmljaF9yZXMkcGF0aHdheV9uYW1lCm15b19lbnJpY2hlZF9nZW5lcyA9IG15b19lbnJpY2hfcmVzWzMsImdlbmVJRCJdICU+JSBzdHJzcGxpdChzcGxpdCA9ICIvIikgJT4lIC5bWzFdXSAlPiUgYyguLG15b19wcm90ZWluX21hcmtlcnMpICNhZGQgb3JpZ2luYWwgbWFya2VycwpgYGAKCmBgYHtyfQptZXNzYWdlKCJnZW5lcyBpbiBteW8gc2NvcmU6IikKbXlvX2VucmljaGVkX2dlbmVzCgptZXNzYWdlKCJnZW5lcyBpbiBsdW0gc2NvcmU6IikKbHVtX2VucmljaGVkX2dlbmVzCgpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1AZGF0YVtteW9fZW5yaWNoZWRfZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbHVtX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyMgZW5yaWNoZWQgZ2VuZXMgYW5kIGluIG9yaWdpbmFsIHNjb3JlCmBgYHtyfQpteW9fZW5yaWNoZWRfZ2VuZXMgPSBteW9fZW5yaWNoZWRfZ2VuZXNbbXlvX2VucmljaGVkX2dlbmVzICVpbiUgb3JpZ2luYWxfbXlvX2dlbmVzXQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoZWRfZ2VuZXNbbHVtX2VucmljaGVkX2dlbmVzICVpbiUgb3JpZ2luYWxfbHVtX2dlbmVzXQoKYGBgCgpgYGB7cn0KCm1lc3NhZ2UoImdlbmVzIGluIG15byBzY29yZToiKQpteW9fZW5yaWNoZWRfZ2VuZXMKCm1lc3NhZ2UoImdlbmVzIGluIGx1bSBzY29yZToiKQpsdW1fZW5yaWNoZWRfZ2VuZXMKbXlvc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbXlvX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXUBkYXRhW2x1bV9lbnJpY2hlZF9nZW5lcyxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLGZlYXR1cmVzID0gImVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8iKQoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2MxX2NhbmNlcl9jZWxscyx2YXJzID0gImVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PWVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8pKSArIAogIGdlb21fZGVuc2l0eSgpIAopCmBgYAoKCiMjIHstfQoKCiMgSFBWCgpPbmx5IEhNU0MgY2FuY2VyIGNlbGxzOgoKYGBge3J9CkhQVjMzX1AzID0gZnJlYWQoIi4vRGF0YS9IUFYzM19QMy50eHQiLGNvbC5uYW1lcyA9IGMoInBsYXRlIiwicmVhZHMiKSkgJT4lIGFzLmRhdGEuZnJhbWUoKQpIUFYzM19QMy5kZiA9IEhQVjMzX1AzICU+JSBtdXRhdGUoCiAgcGxhdGUgPSBnc3ViKHggPUhQVjMzX1AzJHBsYXRlLCByZXBsYWNlbWVudCA9ICIiLHBhdHRlcm4gPSAiXy4qJCIpIAogICU+JSBnc3ViKHBhdHRlcm4gPSAiLVAiLHJlcGxhY2VtZW50ID0gIi5QIikgCiAgJT4lIGdzdWIocGF0dGVybiA9ICItIixyZXBsYWNlbWVudCA9ICJfIiwpCiAgKQpIUFYzM19QMy5kZiA9IEhQVjMzX1AzLmRmICU+JSBkcGx5cjo6ZmlsdGVyKEhQVjMzX1AzLmRmJHBsYXRlICVpbiUgY29sbmFtZXMoYWNjMV9jYW5jZXJfY2VsbHMpKQpyb3duYW1lcyhIUFYzM19QMy5kZikgIDwtIEhQVjMzX1AzLmRmJHBsYXRlCkhQVjMzX1AzLmRmJHBsYXRlID0gTlVMTAoKCkhQVjMzX1AyID0gZnJlYWQoIi4vRGF0YS9IUFYzM19QMi50eHQiLGNvbC5uYW1lcyA9IGMoInBsYXRlIiwicmVhZHMiKSkgJT4lIGFzLmRhdGEuZnJhbWUoKQpIUFYzM19QMi5kZiA9IEhQVjMzX1AyICU+JSBtdXRhdGUoCiAgcGxhdGUgPSBnc3ViKHggPUhQVjMzX1AyJHBsYXRlLCByZXBsYWNlbWVudCA9ICIiLHBhdHRlcm4gPSAiXy4qJCIpIAogICU+JSBnc3ViKHBhdHRlcm4gPSAicGxhdGUyLSIscmVwbGFjZW1lbnQgPSAicGxhdGUyXyIsKQogICU+JSBnc3ViKHBhdHRlcm4gPSAiLSIscmVwbGFjZW1lbnQgPSAiXFwuIiwpCiAgKQpIUFYzM19QMi5kZiA9IEhQVjMzX1AyLmRmICU+JSBkcGx5cjo6ZmlsdGVyKEhQVjMzX1AyLmRmJHBsYXRlICVpbiUgY29sbmFtZXMoYWNjMV9jYW5jZXJfY2VsbHMpKQpyb3duYW1lcyhIUFYzM19QMi5kZikgIDwtIEhQVjMzX1AyLmRmJHBsYXRlCkhQVjMzX1AyLmRmJHBsYXRlID0gTlVMTAoKSFBWMzMgPSByYmluZChIUFYzM19QMy5kZixIUFYzM19QMi5kZikKYWNjMV9jYW5jZXJfY2VsbHMgPSBBZGRNZXRhRGF0YShvYmplY3QgPSBhY2MxX2NhbmNlcl9jZWxscyxtZXRhZGF0YSA9IEhQVjMzLGNvbC5uYW1lID0gIkhQVjMzLnJlYWRzIikKRmVhdHVyZVBsb3QoYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiSFBWMzMucmVhZHMiLG1heC5jdXRvZmYgPSA0MCkKYGBgCmBgYHtyfQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiSFBWMzMucmVhZHMiKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PUhQVjMzLnJlYWRzKSkgKyAKICBnZW9tX2RlbnNpdHkoKQopCmBgYAoK